package cn.mengfly.testnrz.im.server;

import cn.mengfly.testnrz.im.codec.ProtobufDecoder;
import cn.mengfly.testnrz.im.codec.ProtobufEncoder;
import cn.mengfly.testnrz.im.server.handler.ChatRedirectHandler;
import cn.mengfly.testnrz.im.server.handler.HeartBeatServerHandler;
import cn.mengfly.testnrz.im.server.handler.LoginRequestHandler;
import cn.mengfly.testnrz.im.server.handler.ServerExceptionHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class ChatServer {

    private int port;

    public ChatServer(int port) {
        this.port = port;
    }

    private final EventLoopGroup bg = new NioEventLoopGroup();
    private final EventLoopGroup wg = new NioEventLoopGroup();

    private ServerBootstrap b = new ServerBootstrap();

    private final LoginRequestHandler loginRequestHandler = new LoginRequestHandler();
    private final ServerExceptionHandler serverExceptionHandler = new ServerExceptionHandler();
    private final ChatRedirectHandler chatRedirectHandler = new ChatRedirectHandler();

    public void run() {
        try {
            b.group(bg, wg);
            b.channel(NioServerSocketChannel.class);
            b.localAddress(port);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            b.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) {
                    ch.pipeline().addLast(new ProtobufDecoder());
                    ch.pipeline().addLast(new ProtobufEncoder());
                    ch.pipeline().addLast(new HeartBeatServerHandler());
                    ch.pipeline().addLast(loginRequestHandler);
                    ch.pipeline().addLast(chatRedirectHandler);
                    ch.pipeline().addLast(serverExceptionHandler);
                }
            });
            ChannelFuture channelFuture = b.bind().sync();
            System.out.println("【IM】服务启动，端口" + channelFuture.channel().localAddress());
            ChannelFuture future = channelFuture.channel().closeFuture();
            future.sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            wg.shutdownGracefully();
            bg.shutdownGracefully();
        }
    }

}
